package com.example.movie.mate.service.impl;

import com.example.movie.mate.dao.cache.IMovieCacheRepository;
import com.example.movie.mate.dao.mapper.MovieMapper;
import com.example.movie.mate.exception.ServiceException;
import com.example.movie.mate.pojo.entity.Movie;
import com.example.movie.mate.pojo.param.MovieAddNewParam;
import com.example.movie.mate.pojo.vo.MovieVO;
import com.example.movie.mate.service.IMovieService;
import com.example.movie.mate.web.StateCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@Slf4j
@Service
public class MovieServiceImpl implements IMovieService {

    @Autowired
    private MovieMapper movieMapper;
    @Autowired
    private IMovieCacheRepository movieCacheRepository;

    @Override
    public void addNew(MovieAddNewParam param) {
        // 将电影数据插入到MySQL数据库中
        Movie movie = new Movie();
        BeanUtils.copyProperties(param, movie);
        movie.setIsOnSchedule(0);
        movieMapper.insert(movie);

        // 将数据缓存到Redis中：单项数据
        MovieVO movieVO = new MovieVO();
        BeanUtils.copyProperties(movie, movieVO);
        movieCacheRepository.save(movieVO);
        // 将数据缓存到Redis中：未上映列表的项
        movieCacheRepository.saveNotOnScheduleListItem(movieVO);
    }

    @Override
    public MovieVO selectById(Long id) {
        MovieVO findResult = movieCacheRepository.selectById(id);
        if (findResult == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "电影不存在");
        }
        return findResult;
    }

    @Override
    public List<MovieVO> selectAllOnSchedule() {
        List<MovieVO> movieList = movieCacheRepository.selectAllOnSchedule();
        Collections.sort(movieList, Comparator.comparing(MovieVO::getScheduleStartTime));
        return movieList;
    }

    @Override
    public List<MovieVO> selectAllNotOnSchedule() {
        List<MovieVO> movieList = movieCacheRepository.selectAllNotOnSchedule();
        Collections.sort(movieList, Comparator.comparing(MovieVO::getReleaseDate));
        return movieList;
    }

    @Override
    public void rebuildCache() {
        movieCacheRepository.deleteAllItems();
        movieCacheRepository.deleteAllOnSchedule();
        movieCacheRepository.deleteAllNotOnSchedule();

        List<MovieVO> onScheduleMovieList = movieMapper.selectAllByIsOnSchedule(Movie.ScheduleState.ON_SCHEDULE);
        movieCacheRepository.saveOnScheduleList(onScheduleMovieList);
        for (MovieVO movie : onScheduleMovieList) {
            movieCacheRepository.save(movie);
        }

        List<MovieVO> notOnScheduleMovieList = movieMapper.selectAllByIsOnSchedule(Movie.ScheduleState.NOT_ON_SCHEDULE);
        movieCacheRepository.saveNotOnScheduleList(notOnScheduleMovieList);
        for (MovieVO movie : notOnScheduleMovieList) {
            movieCacheRepository.save(movie);
        }
    }

}